package com.activenetwork.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateUtil {
	
	private String format;
	/**
	 * default format "MM/dd/yyyy"
	 * @param format
	 */
	public DateUtil(){
		this.format = "MM/dd/yyyy";
	}
	
	public DateUtil(String format){
		this.format = format;
	}
	/**
	 * Transform normal Calendar interface to XMLGregorianCalendar
	 * @param cal
	 * @return
	 * @throws DatatypeConfigurationException
	 */
	public static XMLGregorianCalendar toXMLGregorianCalendar(Calendar cal) throws DatatypeConfigurationException{
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1; // GregorianCalendar month from 0 but XMLGregorianCalendar month from 1
		int day = cal.get(Calendar.DATE);
		int hour = cal.get(Calendar.HOUR);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		int minisecond = cal.get(Calendar.MILLISECOND);
		
		return DatatypeFactory.newInstance().newXMLGregorianCalendar(year, month, day, hour, minute, second, minisecond, DatatypeConstants.FIELD_UNDEFINED);
		
	}
	/**
	 * Transform XMLGregorianCalendar to normal Calendar interface
	 * @param xmlGregorianCalendar
	 * @return
	 */
	public static Calendar toCalendar(XMLGregorianCalendar xmlGregorianCalendar){
		return xmlGregorianCalendar.toGregorianCalendar();
	}
	/**
	 * Return the string for time dropdown option like "01:15"
	 * @param xmlGregorianCalendar
	 * @return
	 */
	public static String toTimeOption(XMLGregorianCalendar xmlGregorianCalendar){
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String s = sdf.format(xmlGregorianCalendar.toGregorianCalendar().getTime());
		return s.substring(0,5);
	}
	
	public static XMLGregorianCalendar asTimeOption(int hour, int minute) throws DatatypeConfigurationException{
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR, hour);
		cal.set(Calendar.MINUTE, minute);
		cal.set(Calendar.SECOND, 00);
		return toXMLGregorianCalendar(cal);
	}
	/**
	 * Calculate how many days between to calendar
	 * @param cal1
	 * @param cal2
	 * @return
	 */
	public static int calculateBetween(Calendar cal1, Calendar cal2){
		long between_days =  (cal1.getTimeInMillis() - cal2.getTimeInMillis())/(1000*3600*24);
		return Integer.parseInt(String.valueOf(between_days));
	}
	
	public static int calculateBetween(String date1, String date2, String format) throws ParseException{
		SimpleDateFormat sdf= new SimpleDateFormat(format);
		Date d1 = sdf.parse(date1);
		Date d2 = sdf.parse(date2); 
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(d1);
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(d2);
		return calculateBetween(calendar1, calendar2);
	}
	/**
	 * Time stamp generate
	 * @return
	 */
	public static String generateTimeStamp(){
	  	Date date = Calendar.getInstance().getTime();
		return new SimpleDateFormat("yyyyMdhhmmss").format(date);
	}
	/**
	 * Input a calendar representing "05/27/2012" 
	 * Get String "05/27/2012"
	 * Format is in constructor
	 * @param calendar
	 * @return
	 */
	public String toString(Calendar calendar){
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(calendar.getTime());
	}
	/**
	 * Input a string like "05/27/2012"
	 * Get the calendar representing "05/27/2012"
	 * Format is in constructor
	 * @param dateStr
	 * @return
	 * @throws ParseException
	 */
	public Calendar toCalendar(String dateStr) throws ParseException{
		SimpleDateFormat sdf= new SimpleDateFormat(format);
		Date date = sdf.parse(dateStr); 
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}
	/**
	 * Input a calendar representing "05/20/2012" and
	 * Calculate 7 days offset (can be positive or negative)
	 * return a string like "05/27/2012"
	 * @param calendar
	 * @param offset
	 * @return
	 */
	public String stringOffset(Calendar calendar, int offset, boolean positive){
		return toString(calendarOffset(calendar, offset, positive));
	}
	/**
	 * Input a string like "05/20/2012" and
	 * Calculate 7 days offset (can be positive or negative)
	 * return a string like "05/27/2012"
	 * @param dateString
	 * @param offset
	 * @return
	 */
	public String stringOffset(String dateString, int offset, boolean positive) throws ParseException{
		return toString(calendarOffset(dateString, offset, positive));
	}
	/**
	 * Input a calendar representing "05/20/2012" and
	 * Calculate 7 days offset (can be positive or negative)
	 * return a calendar representing "05/27/2012"
	 * @param calendar
	 * @param offset
	 * @return
	 */
	public Calendar calendarOffset(Calendar calendar, int offset, boolean positive){
		// protection copy
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
		cal.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
		cal.set(Calendar.DATE, calendar.get(Calendar.DATE));
		// do calculation
		if(positive){
			cal.add(Calendar.DATE, offset);
		}else{
			cal.add(Calendar.DATE, (0 - offset));
		}
		return cal;
	}
	/**
	 * Input a string like "05/20/2012" and
	 * Calculate 7 days offset (can be positive or negative)
	 * return a calendar representing "05/27/2012"
	 * @param dateString
	 * @param offset
	 * @return
	 */
	public Calendar calendarOffset(String dateString, int offset, boolean positive) throws ParseException{
		Calendar cal = toCalendar(dateString);
		// do calculation
		if(positive){
			cal.add(Calendar.DATE, offset);
		}else{
			cal.add(Calendar.DATE, (0 - offset));
		}
		return cal;
	}
	
	
	
	

}
